﻿using Mapster;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NSwag.Annotations;
using ProxyServer.EntityFrameworkCore;
using ProxyServer.Yarp;
using Yarp.ReverseProxy.Configuration;

namespace ProxyServer.Endpoints;

public record SnapshotDto(List<RouteConfig> Routes, List<ClusterConfig> Clusters);

public static class SnapshotEndpoints
{
    [OpenApiOperation(nameof(ListSnapshots), "", "")]
    public static async Task<List<ProxyConfigSnapshotDto>> ListSnapshots([FromServices] AppDbContext appDb, CancellationToken cancellationToken)
    {
        return await appDb.Snapshots.AsNoTracking().OrderByDescending(x => x.AppliedAt).ProjectToType<ProxyConfigSnapshotDto>().ToListAsync(cancellationToken);
    }

    [OpenApiOperation(nameof(Apply), "Apply a snapshot", "")]
    public static async Task<Results<Ok, NotFound>> Apply([FromRoute] Guid id, [FromServices] AppDbContext appDb, [FromServices] AppProxyConfigProvider appProxy, CancellationToken cancellation)
    {
        var snapshot = await appDb.Snapshots.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id, cancellation);

        if (snapshot is null)
        {
            return TypedResults.NotFound();
        }

        appProxy.Apply(snapshot.Id, snapshot.Routes, snapshot.Clusters);
        return TypedResults.Ok();
    }

    [OpenApiOperation(nameof(GetSnapshotDetails), "Get snaphost details", "")]
    public static async Task<Results<Ok<SnapshotDto>, NotFound>> GetSnapshotDetails([FromRoute] Guid id, [FromServices] AppDbContext appDb, CancellationToken cancellationToken)
    {
        var snapshot = await appDb.Snapshots.FindAsync([id], cancellationToken);

        if (snapshot is null)
        {
            return TypedResults.NotFound();
        }

        return TypedResults.Ok(new SnapshotDto(snapshot.Routes, snapshot.Clusters));
    }
}

public record ProxyConfigSnapshotDto(Guid Id, DateTimeOffset AppliedAt, DateTimeOffset? RemovedAt);